#include "OBJLoader.h"

OBJLoader::OBJLoader(string file) {
	m_file.open(file.c_str());
	if(m_file.fail()) {
		printf("Error: No Input File Found\n");
		return;
	}
	
	do {
		getline(m_file,m_line);
		if(m_line.size() < 1) continue;
		if(m_line[0] == '#') continue;
		if(this->parse()) break;
	}while(!m_file.eof());
}

OBJLoader::~OBJLoader() {
	m_file.close();
}

void OBJLoader::list() {
	printf("OBJ FILE INFO\n Number of vertices: %d\n",(int)vertices.size());
	for(unsigned int i=0; i < vertices.size(); i++) {
		cout << vertices[i].x << " " << vertices[i].y << " " << vertices[i].z << endl;
		//printf("%f %f %f\n",test->vertices[i].x, test->vertices[i].y, test->vertices[i].z);
	}

	printf("Number of Faces: %d\n",(int)faces.size());
	for(unsigned int k=0;k<faces.size();k++) {
		for(unsigned int j=0;j<faces[k].size();j++) {
			printf("%d ",faces[k][j]);
		}
		printf("\n");
	}
}

int OBJLoader::parse() {
	if(m_file.eof()) {
		return 1;
	}

	unsigned int i = 0;
	//Vertex Data
	if(m_line[i] == 'v') {
		//Vertex Position
		i++;
		if(m_line[i] == ' ') {
			vert3f vert;
			string temp = "";	//Store the number in string format
			int count = 0;		//Number of axis data
			while(1) {
				i++;
				if(m_line[i] == ' ' || i > m_line.size()){
					//If the string temp isn't empty its time to get the number
					if(temp.size() > 0) {
						switch(count) {
							case 0: vert.x = (float) strtod(temp.c_str(),NULL);
									break;
							case 1: vert.y = (float) strtod(temp.c_str(),NULL);
									break;
							case 2: vert.z = (float) strtod(temp.c_str(),NULL);
									break;
						}
						temp = "";
						//Finished getting this vertex
						if((++count) > 2) {
							vertices.push_back(vert);
							return 0;
						}
					}
				}else{
					temp += m_line[i];	//Store this part of the number in the string
				}
			}
		}
		//Vertex Normals
		else if(m_line[i] == 'n') {
			normal3f norm;
			string temp = "";	//Store the number in string format
			int count = 0;		//Number of axis data
			while(1) {
				i++;
				if(m_line[i] == ' ' || i > m_line.size()){
					//If the string temp isn't empty its time to get the number
					if(temp.size() > 0) {
						switch(count) {
							case 0: norm.x = (float) strtod(temp.c_str(),NULL);
									break;
							case 1: norm.y = (float) strtod(temp.c_str(),NULL);
									break;
							case 2:	norm.z = (float) strtod(temp.c_str(),NULL);
									break;
						}
						temp = "";
						//Finished getting this vertex
						if((++count) > 2) {
							normals.push_back(norm);
							return 0;
						}
					}
				}else{
					temp += m_line[i];	//Store this part of the number in the string
				}
			}
		}
		//Vertex Texture Mapping Information
		else if(m_line[i] == 't') {
			texture2f tex;
			string temp = "";	//Store the number in string format
			int count = 0;		//Number of axis data
			while(1) {
				i++;
				if(m_line[i] == ' ' || i > m_line.size()){
					//If the string temp isn't empty its time to get the number
					if(temp.size() > 0) {
						switch(count) {
							case 0: tex.u = (float) strtod(temp.c_str(),NULL);
									break;
							case 1: tex.v = (float) strtod(temp.c_str(),NULL);
									break;
						}
						temp = "";
						//Finished getting this vertex information
						if((++count) > 1) {
							texture_pos.push_back(tex);
							return 0;
						}
					}
				}else{
					temp += m_line[i];	//Store this part of the number in the string
				}
			}
		}
	}
	//Specify one or more points (each point is one vertex)
	else if(m_line[i] == 'p') {
		
	}
	//Specify one or more lines	(you can include texture information)
	else if(m_line[i] == 'l') {
		
	}
	//Specify a polygon face
	else if(m_line[i] == 'f') {
		vector<int> tmp;
		string temp = "";	//Store the number in string format
		while(1) {
			i++;
			if((m_line[i] == ' ') || (i > m_line.size()) || m_line[i] == '/'){
				//If the string temp isn't empty its time to get the number
				if(temp.size() > 0) {
					tmp.push_back(atoi(temp.c_str()));
					temp = "";
					if(i > m_line.size()) {
						faces.push_back(tmp);
						return 0;
					}
				}
				if(m_line[i] == '/') {
					//TODO: Store normal and texture information for each face
					printf("This funcionality isn't implemented yet\n");
				}
			}else{
				temp += m_line[i];	//Store this part of the number in the string
			}
		}
	}
	//Specify a group
	else if(m_line[i] == 'g') {
		//TODO: Store group information for some faces
		//printf("This funcionality(group) isn't implemented yet\n");
	}
	
	return 0;
}

